package com.best.oasis.genitrans.web.action.upload;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;

import com.best.oasis.genitrans.common.enums.type.MediaType;
import com.best.oasis.genitrans.common.enums.type.OrderType;
import com.best.oasis.genitrans.common.order.service.SalesOrderService;
import com.best.oasis.genitrans.common.order.service.TransOrderService;
import com.best.oasis.genitrans.common.order.vo.SalesOrderVO;
import com.best.oasis.genitrans.common.order.vo.TransOrderVO;
import com.best.oasis.genitrans.common.upload.service.FileUploadService;
import com.best.oasis.genitrans.common.upload.vo.UploadAttachmentVO;
import com.best.oasis.genitrans.util.exception.GLException;
import com.best.oasis.genitrans.util.helper.FileSource;
import com.best.oasis.genitrans.util.helper.FileStorageHelper;
import com.best.oasis.genitrans.web.action.common.GLBaseAction;

public class MultiFileUploadAction extends GLBaseAction {

    private static final long serialVersionUID = -4302418213791189479L;

    private File[] upload;

    private String[] uploadContentType;

    private String[] uploadFileName;

    private OrderType orderType;

    private String[] orderNum;

    private FileUploadService fileUploadService;

    private SalesOrderService salesOrderService;

    private TransOrderService toService;

    private boolean isSuccess;

    private List<Long> soUploadList = new ArrayList<Long>();

    private List<Long> toUploadList = new ArrayList<Long>();

    public String preUpload() {
        return SUCCESS;
    }

    public void validateDoExecute() {
        if (hasErrors()) {
            return;
        }
        for (int i = 0; i < orderNum.length; i++) {
            checkIfOrderExist(orderType, orderNum[i]);
        }
    }

    private void checkIfOrderExist(OrderType orderType, String orderNum) {
        switch (orderType) {
        case SO:
            SalesOrderVO so = salesOrderService.getSOByCode(orderNum, "salesOrderNumber");
            if (so == null) {
                addActionError("[" + orderNum + "]" + getText("error.so.not.exist"));
            } else {
                soUploadList.add(so.getId());
            }/*
              * else if
              * (!SOStatus.getStatus4List(SOStatus.ATTACHLIST).contains(so
              * .getStatus())) { addActionError("[" + orderNum + "]" +
              * getText("error.so.status.invalid")); }
              */
            break;
        case TO:
            TransOrderVO to = toService.getTOByCode(orderNum, "transOrderNumber");
            if (to == null) {
                addActionError("[" + orderNum + "]" + getText("error.to.not.exist"));
            } else {
                toUploadList.add(to.getId());
            }/*
              * else if
              * (!TOStatus.getStatus4List(TOStatus.ATTACHLIST).contains(to
              * .getStatus())) { addActionError("[" + orderNum + "]" +
              * getText("error.to.status.invalid")); }
              */
            break;
        default:
            addActionError(getText("error.orderType.not.null"));
            break;
        }
    }

    @Override
    public String doExecute() throws GLException {
        upload();
        return SUCCESS;
    }

    public String doUploadPOD() {
        boolean uploadSuccess = upload();
        if (!uploadSuccess) {
            addActionError(getText("error.upload.failed"));
            return INPUT;
        }
        recordOrderPODUpload();
        return SUCCESS;
    }

    public void validateDoUploadPOD() {
        if (hasErrors()) {
            return;
        }
        for (int i = 0; i < orderNum.length; i++) {
            checkIfOrderExist(orderType, orderNum[i]);
        }
    }

    private boolean upload() {
        List<UploadAttachmentVO> attachList = new ArrayList<UploadAttachmentVO>();
        try {
            for (int i = 0; i < upload.length; i++) {
                String[] uploadFileNameArr = uploadFileName[i].split("\\.");
                String extName = uploadFileNameArr[uploadFileNameArr.length - 1];

                String fileName = FileStorageHelper.getFileName(extName);
                String resultUrl = FileStorageHelper.getDownloadURL(FileSource.ATTACHMENT, fileName);

                UploadAttachmentVO attachment = new UploadAttachmentVO();
                attachment.setName(uploadFileName[i]);
                attachment.setFileInDb(true);
                attachment.setContentType(uploadContentType[i]);
                attachment.setMediaType(MediaType.getFileCategory(attachment.getNameSuffix()));
                attachment.setOrderType(orderType);
                attachment.setOrderNum(orderNum[i]);
                attachment.setResultURL(resultUrl);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                FileInputStream fis = new FileInputStream(upload[i]);
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = fis.read(buffer)) > 0) {
                    baos.write(buffer, 0, len);
                }
                byte[] b = baos.toByteArray();
                // attachment.setContent(baos.toByteArray());
                baos.close();
                fis.close();

                attachList.add(attachment);

                if (b.length == 0) {
                    return true;
                }

                File file = FileStorageHelper.createFile(fileName);

                FileUtils.writeByteArrayToFile(file, b);
            }

            fileUploadService.saveAttachments(attachList);
            isSuccess = true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private void recordOrderPODUpload() {
        for (Long soId : soUploadList) {
            salesOrderService.updateSO4PODUpload(soId);
        }
        for (Long toId : toUploadList) {
            toService.updateTO4PODUpload(toId);
        }
    }

    public void validateCheckOrders() {
        for (int i = 0; i < orderNum.length; i++) {
            checkIfOrderExist(orderType, orderNum[i]);
        }
    }

    public List<Long> getSoUploadList() {
        return soUploadList;
    }

    public void setSoUploadList(List<Long> soUploadList) {
        this.soUploadList = soUploadList;
    }

    public List<Long> getToUploadList() {
        return toUploadList;
    }

    public void setToUploadList(List<Long> toUploadList) {
        this.toUploadList = toUploadList;
    }

    public String checkOrders() {
        return SUCCESS;
    }

    public File[] getUpload() {
        return upload;
    }

    public void setUpload(File[] upload) {
        this.upload = upload;
    }

    public String[] getUploadContentType() {
        return uploadContentType;
    }

    public void setUploadContentType(String[] uploadContentType) {
        this.uploadContentType = uploadContentType;
    }

    public String[] getUploadFileName() {
        return uploadFileName;
    }

    public void setUploadFileName(String[] uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    public void setFileUploadService(FileUploadService fileUploadService) {
        this.fileUploadService = fileUploadService;
    }

    public void setSalesOrderService(SalesOrderService salesOrderService) {
        this.salesOrderService = salesOrderService;
    }

    public void setToService(TransOrderService toService) {
        this.toService = toService;
    }

    public OrderType getOrderType() {
        return orderType;
    }

    public void setOrderType(OrderType orderType) {
        this.orderType = orderType;
    }

    public String[] getOrderNum() {
        return orderNum;
    }

    public void setOrderNum(String[] orderNum) {
        this.orderNum = orderNum;
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean isSuccess) {
        this.isSuccess = isSuccess;
    }

}
